﻿/*
   Open Intel 
   Copyright © 2011 – ISC. All Rights Reserved.
*/
using System;
using System.Collections.Generic;
using Caliburn.Micro;
using OI.DataModel;
using OI.Framework;


namespace OI.Async
{
    public class CatalogQuery<T> : IResult
    {
        #region DATA
        public List<T> Results { get; set; }
        public System.Action Query { get; set; }
        public bool ShowUnpublished { get; set; }
        #endregion


        public event EventHandler<ResultCompletionEventArgs> Completed;

        // note: jurisdiction query takes string jurisdictionID, 
        // all other queries require the integer FK for the jurisdiction ID
        public CatalogQuery(object id)
        {
            var client = ServiceClients.CreateCatalogServiceClient();

            // id passed in may be null, string or int 
            string jurisdictionID = null;
            int jurisdictionFK = 0;
            if (id != null)
            {
                if (id is string)
                {
                    jurisdictionID = Convert.ToString(id);
                }
                else if (id is int)
                {
                    jurisdictionFK = Convert.ToInt32(id);
                }
            }

            if (typeof(T) == typeof(OIJurisdiction))
            {
                // return exact juris, else all juris
                if (!string.IsNullOrEmpty(jurisdictionID))
                {
                    client.GetJurisdictionCompleted += (s, e) => ProcessResults(e.Error, e.Result);
                    Query = delegate { client.GetJurisdictionAsync(jurisdictionID); };
                }
                else
                {
                    client.GetJurisdictionsCompleted += (s, e) => ProcessResults(e.Error, e.Result);
                    Query = delegate { client.GetJurisdictionsAsync(); };
                }
            }
            if (typeof(T) == typeof(OICategory))
            {
                client.GetCategoriesCompleted += (s, e) => ProcessResults(e.Error, e.Result);
                Query = delegate { client.GetCategoriesAsync(jurisdictionFK); };
            }
            if (typeof(T) == typeof(OISource))
            {
                client.GetSourcesCompleted += (s, e) => ProcessResults(e.Error, e.Result);
                Query = delegate { client.GetSourcesAsync(jurisdictionFK); };
            }
            if (typeof(T) == typeof(OIDataset))
            {
                client.GetDatasetsCompleted += (s, e) => ProcessResults(e.Error, e.Result);
                Query = delegate { client.GetDatasetsAsync(jurisdictionFK, ShowUnpublished); };
            }
            if (typeof(T) == typeof(OIApp))
            {
                client.GetAppsCompleted += (s, e) => ProcessResults(e.Error, e.Result);
                Query = delegate { client.GetAppsAsync(jurisdictionFK); };
            }
        }


        public void Execute(ActionExecutionContext context)
        {
            Query();
        }


        private void ProcessResults(Exception ex, string json)
        {
            try
            {
                if (ex != null)
                {
                    throw (ex);
                }

                var results = (ICollection<T>)(MessageSerializer.Deserialize(json));
                Results = new List<T>(results);
            }
            catch (Exception ex2)
            {
                IoC.Get<IShell>().HandleException(ex2, "Error fetching: " + typeof(T) + " -> JSON: " + json);
            }
            finally
            {
                Completed(this, new ResultCompletionEventArgs());
            }
        }
    }
}
